#ifndef __M_ACCEPTOR_H__
#define __M_ACCEPTOR_H__

#pragma once

#include "log.hpp"
#include "socket.hpp"
#include "channel.hpp"
#include "eventLoop.hpp"

class Acceptor
{
using AcceptorCallback = std::function<void(int)>;

private:
    Socket _listensock;
    int _listenfd;
    std::unique_ptr<Channel> _channel;//对监听套接字进行事件监控管理
    EventLoop* _loop;
    AcceptorCallback _cb;

private:
    int createServer(uint16_t port)
    {
        if (!_listensock.createServer(port))
            exit(-1);
        return _listensock.getFd();
    }

    void handleRead()
    {
        int sockfd = _listensock.Accept();
        if (sockfd == -1)
        {
            LOG(ERR, "accept new sock error");
            exit(-1);
        }
        if (_cb)
            _cb(sockfd);
    }

public:
    Acceptor(uint16_t port, EventLoop* loop)
    : _listenfd(createServer(port)),
      _channel(new Channel(_listenfd, loop)),
      _loop(loop)
    {
        /*
        不能在构造函数内开启读事件监控 因为如果立即有新连接到来便会触发读事件 而此时AcceptorCallback还未设置
        就会出现新连接无法被管理(没有构造Connection对象) 以及描述符泄露等问题
        */
        _channel->setReadCallback(std::bind(&Acceptor::handleRead, this));
        // _channel->monitorRead();
    }

    void listen() { _channel->monitorRead(); }

    /*
    该回调由server模块传入 大致流程为:
    1.根据sockfd创建Connection
    2.将Connection对象添加到server管理的hash中
    3.为Connection对象设置阶段性回调 开启非活跃超时销毁和读事件监控
    */
    void setAcceptorCallback(const AcceptorCallback& cb) { _cb = cb; }
    
};

#endif
